package mathsys2;

import java.util.Objects;

/**
 * 减法算式子类：继承AbstractArithmetic抽象类，实现减法特有的逻辑
 * 核心职责：
 * 1. 实现减法结果计算（num1 - num2），并校验差≥0（两份实验共同约束）；
 * 2. 实现减法非交换律去重（a-b与b-a视为不同，《模块化软件构造》故事三需求）；
 * 3. 重写hashCode()确保与equals()逻辑一致，支持集合去重。
 */
public class SubtractionArithmetic extends AbstractArithmetic {

    /**
     * 构造方法：调用父类构造完成共性校验，限定运算符为'-'
     * @param num1 被减数（0-100，需≥num2，实验约束）
     * @param num2 减数（0-100，需≤num1，实验约束）
     * @throws IllegalArgumentException 当减法差<0或参数违反父类约束时抛出
     */
    public SubtractionArithmetic(int num1, int num2) {
        // 调用父类构造：父类自动校验num1/num2在0-100，且operator为'-'
        super(num1, num2, '-');
    }


    // -------------------------- 实现父类抽象方法：减法结果计算 --------------------------
    /**
     * 计算减法结果，并校验差≥0（《面向对象软件构造》3.3节约束，《模块化软件构造》故事二需求）
     * 若差<0，抛出异常；否则赋值给父类的protected属性result
     */
    @Override
    public void calculate() {
        int difference = getNum1() - getNum2();
        // 校验减法差≥0（父类未处理该约束，子类补充减法特有校验）
        if (difference < 0) {
            throw new IllegalArgumentException("减法结果为负数（两份实验共同约束）：" + getNum1() + "-" + getNum2() + "=" + difference);
        }
        // 赋值结果到父类的result属性（protected修饰，子类可直接访问）
        this.result = difference;
    }


    // -------------------------- 实现父类抽象方法：减法非交换律去重 --------------------------
    /**
     * 判断两个减法算式是否重复（a-b与b-a视为不同，《模块化软件构造》故事三需求）
     * @param obj 待比较的对象
     * @return true=重复，false=不重复
     */
    @Override
    public boolean equals(Object obj) {
        // 1. 引用相同：直接返回true
        if (this == obj) {
            return true;
        }
        // 2. 对象为null或类型不同：返回false（确保仅与减法子类比较）
        if (obj == null || getClass() != obj.getClass()) {
            return false;
        }
        // 3. 类型转换：转为减法子类实例
        SubtractionArithmetic other = (SubtractionArithmetic) obj;
        // 4. 非交换律判定：严格匹配被减数（num1）和减数（num2），顺序不同则视为不同
        return getNum1() == other.getNum1() && getNum2() == other.getNum2();
    }


    // -------------------------- 重写hashCode()：确保与equals()逻辑一致 --------------------------
    /**
     * 按“被减数+减数+运算符”计算哈希值（确保a-b与b-a的hashCode不同，支持集合去重）
     * 实验用途：配合HashSet等集合存储时，避免非交换律的减法算式被误判为重复对象
     * @return 减法算式的哈希值
     */
    @Override
    public int hashCode() {
        // 严格按num1（被减数）、num2（减数）、运算符'-'计算哈希，与加法子类区分
        return Objects.hash(getNum1(), getNum2(), getOperator());
    }
}